package com.alinesno.cloud.initializr.starter.dynamicSqlSession;

import java.util.Objects;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import com.alibaba.druid.pool.DruidDataSource;
import com.alinesno.cloud.initializr.starter.constants.DbType;
import com.alinesno.cloud.initializr.starter.entity.InitializrDbListEntity;

public class SqlSessionFactoryUtil {
	public SqlSession creatSession(InitializrDbListEntity dbListEntity) throws Exception {
		DruidDataSource dataSource = new DruidDataSource();
		try {
			String ecapseUserName = StringEscapeUtils
					.escapeJava(StringEscapeUtils.unescapeHtml(dbListEntity.getDbUsername()));
			String ecapseUserPass = StringEscapeUtils
					.escapeJava(StringEscapeUtils.unescapeHtml(dbListEntity.getDbPasswd()));
			dataSource.setDriverClassName(resolveDriverName(dbListEntity));
			dataSource.setUsername(ecapseUserName);
			dataSource.setPassword(ecapseUserPass);
			String url = String.format(
					"jdbc:mysql://%s:%s/%s?useUnicode=true&characterEncoding=utf-8?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false&serverTimezone=GMT",
					dbListEntity.getDbUrl(), dbListEntity.getDbPort(), dbListEntity.getDbName());

			String ecapseUrl = StringEscapeUtils.escapeJava(StringEscapeUtils.unescapeHtml(url));
			makeThrowOnException(dataSource);
			dataSource.setUrl(ecapseUrl);
			// 构建SQL会话
			SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
			ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
			sqlSessionFactoryBean.setDataSource(dataSource);
			sqlSessionFactoryBean.setMapperLocations(resourcePatternResolver.getResources("classpath*:mapper/*.xml"));
			return Objects.requireNonNull(sqlSessionFactoryBean.getObject()).openSession();
		} catch (Exception e) {
			dataSource.close();
			throw e;
		}

	}

	private void makeThrowOnException(DruidDataSource dataSource) {
		// 以下设置保证连接错误时能退出,而不是无限重试
		dataSource.setConnectionErrorRetryAttempts(0);
		dataSource.setMaxWait(1000 * 10);
		dataSource.setBreakAfterAcquireFailure(true);
		dataSource.setFailFast(true);
		dataSource.setInitialSize(3);
	}

	private String resolveDriverName(InitializrDbListEntity entity) {
		switch (entity.getDbType()) {
		case DbType.MY_SQL: {
			return DbType.MYSQL_DRIVER_NAME;
		}
		default: {
			return "";
		}
		}
	}
}
